package reflect;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Scanner;

/**
 * java反射机制
 *
 * 反射是java的动态机制，可以允许我们在程序[运行期间]再确定实例化，调用某个方法，操作某个属性。
 * 反射机制大大的提高了代码的灵活度，但是会有更高的系统开销和较慢的运行效率。
 * 因此反射机制不能被过度的使用
 *
 *
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            类对象  Class的实例
            JVM在加载一个类的class文件时，就会同时创建一个Class的实例，使用该实例记录加载的
            类的一切信息(类名，有哪些属性，哪些方法，哪些构造器等)。并且每个被JVM加载的类都有
            且只有一个Class的实例与之对应。
            反射的第一步就是获取要操作的类的类对象，以便程序在运行期间得知要操作的类的一切信息
            然后对其进行响应的操作。

            获取一个类的类对象的常见方式:
            1:类名.class
            例如:
                Class cls = String.class;
                Class cls = int.class;
                注意:基本类型获取类对象只有这一种方式。

            2:Class.forName(String className)
            例如:
                Class cls = Class.forName("java.lang.String");
                这里传入的类名必须是类的完全限定名，即:包名.类名

            3:还可以通过类加载器形式完成
         */

        //获取String的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;

//        Class cls = Class.forName("java.lang.String");

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入类名:");
        String className = scanner.nextLine();
        /*
            java.util.ArrayList
            java.util.HashMap
            java.io.ObjectInputStream
            java.lang.String
         */
        Class cls = Class.forName(className);



        //获取当前类对象所表示的类的完全限定名
        String name = cls.getName();
        System.out.println(name);
        //仅获取类名(不包含包名)
        name = cls.getSimpleName();
        System.out.println(name);
        /*
            Package getPackage()
            获取当前类对象所表示的类的包，返回的Package实例表示该包信息
         */
        Package pack = cls.getPackage();
        String packName = pack.getName();
        System.out.println("包名"+packName);
        /*
            Method[] getMethods()
            获取当前类对象所表示的类中定义的所有公开方法，包含从超类继承下来的方法

            java.lang.reflect.Method类，方法对象
            该类的每一个实例用于表示某个类中定义的一个方法，通过它可以获取其表示的方法中的
            相关信息(方法名，参数个数，参数类型，返回值类型等等，并且还可以调用这个方法)
         */
        Method[] methods = cls.getMethods();
        for(Method method : methods){
            System.out.println(method.getName()+"()");
        }
    }
}


